package com.xci.platform.auth.service;

import com.github.pagehelper.Page;
import com.xci.platform.auth.core.AuthConstant;
import com.xci.platform.auth.core.HistoryModel;
import com.xci.platform.auth.core.HistoryOperateType;
import com.xci.platform.core.BoolMessage;
import com.xci.platform.auth.dao.DocDao;
import com.xci.platform.auth.entity.DocEntity;
import com.xci.platform.annotation.OperateUser;
import com.xci.platform.annotation.QueryMap;
import com.xci.platform.helper.CoreHelper;
import com.xci.platform.helper.StringHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 系统文档服务
 */
@Service
public class DocService extends AuthBaseService {

    /**
     * 文档数据访问对象
     */
    @Resource
    private DocDao docDao;

    /**
     * 保存文档
     *
     * @param entity   文档对象
     * @param isCreate 是否新建
     */
    @Validated
    @OperateUser
    @Transactional(rollbackFor = Exception.class)
    public BoolMessage save(DocEntity entity, Boolean isCreate) {
        String msg;
        entity.setTitle(StringHelper.cleanHtml(entity.getTitle()));
        entity.setDocContent(StringHelper.cleanHtml(entity.getDocContent()));
        long startTime = CoreHelper.startWatch();
        if (isCreate) {
            msg = StringHelper.format("新增文档 {}", entity.getTitle());
            docDao.insert(entity);
            //region 历史记录
            operateHistory(buildHistory()
                    .operateType(HistoryOperateType.Insert)
                    .keyValue(entity.getId())
                    .message(msg)
                    .after(entity)
            );
            //endregion
        } else {
            msg = StringHelper.format("修改文档 {}", entity.getTitle());
            DocEntity oldEntity = queryById(entity.getId());
            docDao.update(entity);
            //region 历史记录
            operateHistory(buildHistory()
                    .operateType(HistoryOperateType.Update)
                    .keyValue(entity.getId())
                    .message(msg)
                    .before(oldEntity)
                    .after(entity)
            );
            //endregion
        }
        // 操作日志
        operateLog(AuthConstant.SystemModule.Doc, msg, CoreHelper.stopWatch(startTime));
        return BoolMessage.True;
    }

    /**
     * 删除文档
     *
     * @param ids 文档主键数组
     */
    @Validated
    @Transactional(rollbackFor = Exception.class)
    public BoolMessage delete(@NotEmpty(message = "请指定删除的文档主键数组") String[] ids) {
        for (String id : ids) {
            DocEntity oldEntity = docDao.queryById(id);
            if (oldEntity == null) continue;
            long startTime = CoreHelper.startWatch();
            docDao.delete(id);
            String msg = StringHelper.format("删除文档 {}", oldEntity.getTitle());
            //region 历史记录
            operateHistory(buildHistory()
                    .operateType(HistoryOperateType.Delete)
                    .keyValue(id)
                    .message(msg)
                    .before(oldEntity)
            );
            //endregion
            // 操作日志
            operateLog(AuthConstant.SystemModule.Doc, msg, CoreHelper.stopWatch(startTime));
        }
        return BoolMessage.True;
    }

    /**
     * 更新文档启用状态
     *
     * @param id     文档主键
     * @param status 是否启用(1:启用 0:禁用)
     */
    @Validated
    @Transactional(rollbackFor = Exception.class)
    public BoolMessage updateStatus(@NotNull(message = "请指定更新状态的文档主键") String id,
                                    @NotNull(message = "请指定状态") Integer status) {
        long startTime = CoreHelper.startWatch();
        docDao.updateStatus(id, status);
        // 操作日志
        String msg = StringHelper.format("更新文档状态 主键: {} 更新后状态: {}",
                id, status);
        operateLog(AuthConstant.SystemModule.Doc, msg, CoreHelper.stopWatch(startTime));
        return BoolMessage.True;
    }

    /**
     * 根据文档主键获取文档对象
     *
     * @param id 文档主键
     * @return 返回指定文档主键的文档对象
     */
    @Validated
    public DocEntity queryById(@NotNull(message = "请指定文档主键") String id) {
        return docDao.queryById(id);
    }

    /**
     * 查询文档列表
     *
     * @param params 查询参数
     * @return 返回符合查询条件的文档列表
     */
    @QueryMap
    public List<DocEntity> query(Map params) {
        return docDao.query(params);
    }

    /**
     * 查询文档分页列表
     *
     * @param params 查询参数
     * @return 返回符合查询条件的文档分页列表
     */
    @QueryMap
    public Page<DocEntity> queryPage(Map params) {
        return (Page<DocEntity>) docDao.query(params);
    }

    /**
     * 生成历史记录对象
     */
    private HistoryModel.HistoryModelBuilder buildHistory() {
        return HistoryModel.builder()
                .tableName("sys_doc")
                .tableCaption("系统文档")
                .keyName("id");
    }
}
